package com.uit.httt04.duongvanlam.facedetection.imageprocessing;

import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import static com.googlecode.javacv.cpp.opencv_highgui.*;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.util.Log;

public class ImageProcessing
{
	public static String TAG = "ImageProcessing";

	public static IplImage LoadAndScale(String ImagePath, int NewHeight, int NewWidth) throws Exception
	{
		try
		{
			Bitmap originalBitmap = BitmapFactory.decodeFile(ImagePath);
			//
			// <-- Resize
			//

			if (originalBitmap == null)
				throw new Exception("File not found");

			if (originalBitmap.getWidth() != NewWidth || originalBitmap.getHeight() != NewHeight)
			{
				Bitmap resizedBitmap = Bitmap.createScaledBitmap(originalBitmap, NewWidth, NewHeight, false);
				//
				//
				//
				FileOutputStream newFile = new FileOutputStream(ImagePath);
				resizedBitmap.compress(Bitmap.CompressFormat.JPEG, 90, newFile);
				newFile.flush();
				newFile.close();
				newFile = null;
				//
				//F
				//
				resizedBitmap.recycle();
				resizedBitmap = null;
			}
			//
			// Resize -->
			//
			originalBitmap.recycle();
			originalBitmap = null;

			IplImage Image8bit = cvLoadImage(ImagePath);

			return Image8bit;
		}
		catch (Exception e)
		{
			Log.d(TAG, e.toString());
			throw e;
		}
	}

	public static IplImage EqualizeHist(IplImage oldImage) throws Exception
	{
		try
		{
			IplImage Image8bit = cvCreateImage(cvSize(oldImage.width(), oldImage.height()), IPL_DEPTH_8U, 1);
			cvCvtColor(oldImage, Image8bit, CV_RGB2GRAY);
			cvEqualizeHist(Image8bit, Image8bit);
			//
			// <-- Convert 8bit to 32 bit
			//
			IplImage Image32bit = cvCreateImage(cvSize(Image8bit.width(), Image8bit.height()), IPL_DEPTH_32F, Image8bit.nChannels());
			cvConvertScale(Image8bit, Image32bit, 1, 0);
			//
			// Convert 8bit to 32 bit -->
			//

			cvReleaseImage(Image8bit);

			return Image32bit;
		}
		catch (Exception e)
		{
			Log.d(TAG, e.toString());
			throw e;
		}
	}

	public static void YCrCbToRGB2(int[] pixels, byte[] data, int width, int height)
	{
		int size = width * height;
		int offset = size;
		int u, v, y1, y2, y3, y4;

		for (int i = 0, k = 0; i < size; i += 2, k += 2)
		{
			y1 = data[i] & 0xff;
			y2 = data[i + 1] & 0xff;
			y3 = data[width + i] & 0xff;
			y4 = data[width + i + 1] & 0xff;

			u = data[offset + k] & 0xff;
			v = data[offset + k + 1] & 0xff;
			u = u - 128;
			v = v - 128;

			pixels[i] = YCrCbToRGB2_support(y1, u, v);
			pixels[i + 1] = YCrCbToRGB2_support(y2, u, v);
			pixels[width + i] = YCrCbToRGB2_support(y3, u, v);
			pixels[width + i + 1] = YCrCbToRGB2_support(y4, u, v);

			if (i != 0 && (i + 2) % width == 0)
				i += width;
		}
	}

	private static int YCrCbToRGB2_support(int y, int u, int v)
	{
		int r, g, b;

		r = y + (int) 1.402f * u;
		g = y - (int) (0.344f * v + 0.714f * u);
		b = y + (int) 1.772f * v;
		r = r > 255 ? 255 : r < 0 ? 0 : r;
		g = g > 255 ? 255 : g < 0 ? 0 : g;
		b = b > 255 ? 255 : b < 0 ? 0 : b;
		return 0xff000000 | (r << 16) | (g << 8) | b;
	}

	public static CvMat YCrCbToRGB(CvMat DataYCrCb, int height, int width) throws Exception
	{
		try
		{
			CvMat result = cvCreateMat(height, width, CV_8UC3);
			cvCvtColor(DataYCrCb, result, CV_YUV2BGR_NV21);
			return result;
		}
		catch (Exception e)
		{
			Log.d(TAG, e.toString());
			throw e;
		}
	}

	public static void SaveImageFromBitmap(Bitmap bitmap, String imagePath) throws Exception, IOException
	{
		try
		{
			File bitmapFile = new File(imagePath);
			OutputStream fileOutputStream = new FileOutputStream(bitmapFile);
			bitmap.compress(CompressFormat.PNG, 100, fileOutputStream);
			fileOutputStream.close();
			fileOutputStream = null;
		}
		catch (IOException iOException)
		{
			throw iOException;
		}
		catch (Exception e)
		{
			throw e;
		}
	}

	public static void SaveImageFromIplImage(IplImage iplImage, String imagePath) throws Exception
	{
		try
		{
			cvSaveImage(imagePath, iplImage);
		}
		catch (Exception e)
		{
			throw e;
		}
	}
}
